using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Security;
using System.Web;
using System.Xml;

using Warcraft.Armory;
using Warcraft.Armory.Character;

namespace Warcraft.Armory.Guild
{

    public class WarcraftArmoryGuildException : Exception
    {

        public WarcraftArmoryGuildException(string message): base(message)
        {
        }

    }

    public class WarcraftArmoryGuild
    {

        private WarcraftArmory armory;
        private string realm;
        private string name;
        private WarcraftArmoryFaction faction;
        private WarcraftArmoryGuildMembers members;

        public WarcraftArmoryGuild(WarcraftArmory armory, string realm, string name)
        {
            // Set up various members
            this.armory = armory;

            members = new WarcraftArmoryGuildMembers(armory,this);

            // Set up base search url
            string url = "guild-info.xml?r={realm}&n={guildname}&p=1";

            // Replace realm placeholder
            url = url.Replace("{realm}",HttpUtility.UrlEncode(realm));

            // Replace guild name placeholder
            url = url.Replace("{guildname}",HttpUtility.UrlEncode(name));

            // Dispatch request
            HttpWebResponse response = armory.Request(url);

            // Create XML document
            XmlDocument document = new XmlDocument();

            // Load response into document
            document.Load(response.GetResponseStream());

            // Get master guild node
            XmlNode node = document.SelectSingleNode("/page/guildKey");

            // Get node attributes
            this.realm = node.Attributes["realm"].Value;
            this.name = node.Attributes["name"].Value;
            this.faction = (WarcraftArmoryFaction)int.Parse(node.Attributes["factionId"].Value);

            // Get characters
            XmlNodeList nodes = document.SelectNodes("/page/guildInfo/guild/members/character");

            //
            for (int i = 0; i < nodes.Count; i++) {
                // Get node
                XmlNode charnode = nodes[i];

                // Make sure it's a character node, if not simply skip
                if (charnode.LocalName.ToLower() != "character") continue;

                // Get node attributes
                WarcraftArmoryCharacterClass chrclass = (WarcraftArmoryCharacterClass)int.Parse(charnode.Attributes["classId"].Value);
                WarcraftArmoryGender gender = (WarcraftArmoryGender)int.Parse(charnode.Attributes["genderId"].Value);
                int level = int.Parse(charnode.Attributes["level"].Value);
                string charname = charnode.Attributes["name"].Value;
                WarcraftArmoryRace race = (WarcraftArmoryRace)int.Parse(charnode.Attributes["raceId"].Value);
                int rank = int.Parse(charnode.Attributes["rank"].Value);

                // Create result
                WarcraftArmoryGuildMember member = new WarcraftArmoryGuildMember(armory,this,chrclass,gender,level,charname,race,rank);

                // Add result to results
                members.Add(member);
            }
        }

        /* Methods */

        /* Properties */

        public string Name
        {
            get {
                return name;
            }
        }

        public string Realm
        {
            get {
                return realm;
            }
        }

        public WarcraftArmoryFaction Faction
        {
            get {
                return faction;
            }
        }

        public WarcraftArmoryGuildMembers Members
        {
            get {
                return members;
            }
        }

    }

    public class WarcraftArmoryGuildMembers : ICollection, IEnumerable
    {

        private WarcraftArmory armory;
        private WarcraftArmoryGuild guild;
        private ArrayList list;

        internal WarcraftArmoryGuildMembers(WarcraftArmory armory, WarcraftArmoryGuild guild)
        {
            this.armory = armory;
            this.guild = guild;
            list = new ArrayList();
        }

        /* Methods */

        internal void Add(WarcraftArmoryGuildMember member)
        {
            list.Add(member);
        }

        public IEnumerator GetEnumerator()
        {
            return list.GetEnumerator();
        }

        public void CopyTo(Array array, int arrayIndex)
        {
            list.CopyTo(array,arrayIndex);
        }

        /* Properties */

        public object SyncRoot
        {
            get {
                return this;
            }
        }

        public bool IsSynchronized
        {
            get {
                return false;
            }
        }

        public int Count
        {
            get {
                return list.Count;
            }
        }

        public WarcraftArmoryGuildMember this[int index]
        {
            get {
                return (WarcraftArmoryGuildMember)list[index];
            }
        }

    }

    public class WarcraftArmoryGuildMember
    {
        
        private WarcraftArmory armory;
        private WarcraftArmoryGuild guild;
        private WarcraftArmoryCharacterClass chrclass;
        private WarcraftArmoryGender gender;
        private int level;
        private string name;
        private WarcraftArmoryRace race;
        private int rank;

        internal WarcraftArmoryGuildMember(WarcraftArmory armory, WarcraftArmoryGuild guild, WarcraftArmoryCharacterClass characterClass, WarcraftArmoryGender gender, int level, string name, WarcraftArmoryRace race, int rank)
        {
            this.armory = armory;
            this.guild = guild;
            this.chrclass = characterClass;
            this.gender = gender;
            this.level = level;
            this.name = name;
            this.race = race;
            this.rank = rank;
        }

        /* Methods */

        public WarcraftArmoryCharacter ToCharacter()
        {
            //return new WarcraftArmoryCharacter(armory,guild.Realm,name);
            return null;
        }

        /* Properties */

        public WarcraftArmoryCharacterClass CharacterClass
        {
            get {
                return chrclass;
            }
        }

        public WarcraftArmoryGender Gender
        {
            get {
                return gender;
            }
        }

        public int Level
        {
            get {
                return level;
            }
        }

        public string Name
        {
            get {
                return name;
            }
        }

        public WarcraftArmoryRace Race
        {
            get {
                return race;
            }
        }

        public int Rank
        {
            get {
                return rank;
            }
        }

    }

}
